Skip to content

Conversation

@jhuber6
Copy link
Contributor

@jhuber6 jhuber6 commented Jan 24, 2024

Summary:
A relocatable link through clang -r can go through the
clang-linker-wrapper if offloading is enabled. This will have the effect
of linking the device code and creating the wrapper module. It will then
be merged into the final file. This is useful behavior on its own, but
is likely not what is expected for a -r job.

This patch makes the linker wrapper ignore the device code when doing a
reloctable link. This has the effect of the linker merging the
.llvm.offloading sections in the output object. These will then be
parsed as normal when the executable is finally created.

Even though this doesn't actually perform a reloctable link on the
device code itself, it has a similar effect of combining multiple files
into a single one.

Summary:
A relocatable link through `clang -r` can go through the
clang-linker-wrapper if offloading is enabled. This will have the effect
of linking the device code and creating the wrapper module. It will then
be merged into the final file. This is useful behavior on its own, but
is likely not what is expected for a `-r` job.

This patch makes the linker wrapper ignore the device code when doing a
reloctable link. This has the effect of the linker merging the
`.llvm.offloading` sections in the output object. These will then be
parsed as normal when the executable is finally created.

Even though this doesn't actually perform a reloctable link on the
device code itself, it has a similar effect of combining multiple files
into a single one.
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Jan 24, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 24, 2024

@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: Joseph Huber (jhuber6)

Changes

Summary:
A relocatable link through clang -r can go through the
clang-linker-wrapper if offloading is enabled. This will have the effect
of linking the device code and creating the wrapper module. It will then
be merged into the final file. This is useful behavior on its own, but
is likely not what is expected for a -r job.

This patch makes the linker wrapper ignore the device code when doing a
reloctable link. This has the effect of the linker merging the
.llvm.offloading sections in the output object. These will then be
parsed as normal when the executable is finally created.

Even though this doesn't actually perform a reloctable link on the
device code itself, it has a similar effect of combining multiple files
into a single one.


Full diff: https://github.com/llvm/llvm-project/pull/79314.diff

2 Files Affected:

  • (modified) clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp (+6)
  • (modified) clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td (+3)
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 5485a4b74bf8a8..b682cc293d54b2 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -1356,6 +1356,12 @@ Expected<SmallVector<SmallVector<OffloadFile>>>
 getDeviceInput(const ArgList &Args) {
   llvm::TimeTraceScope TimeScope("ExtractDeviceCode");
 
+  // If the user is requesting a reloctable link we ignore the device code. The
+  // actual linker will merge the embedded device code sections so they can be
+  // linked when the executable is finally created.
+  if (Args.hasArg(OPT_relocatable))
+    return SmallVector<SmallVector<OffloadFile>>{};
+
   StringRef Root = Args.getLastArgValue(OPT_sysroot_EQ);
   SmallVector<StringRef> LibraryPaths;
   for (const opt::Arg *Arg : Args.filtered(OPT_library_path, OPT_libpath))
diff --git a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
index b6d3297987fffe..c59cb0fb3e7cbf 100644
--- a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
+++ b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
@@ -127,6 +127,9 @@ def version : Flag<["--", "-"], "version">, Flags<[HelpHidden]>, Alias<v>;
 def whole_archive : Flag<["--", "-"], "whole-archive">, Flags<[HelpHidden]>;
 def no_whole_archive : Flag<["--", "-"], "no-whole-archive">, Flags<[HelpHidden]>;
 
+def relocatable : Flag<["--", "-"], "relocatable">, Flags<[HelpHidden]>;
+def r : Flag<["-"], "r">, Alias<relocatable>, Flags<[HelpHidden]>;
+
 // link.exe-style linker options.
 def out : Joined<["/", "-", "/?", "-?"], "out:">, Flags<[HelpHidden]>;
 def libpath : Joined<["/", "-", "/?", "-?"], "libpath:">, Flags<[HelpHidden]>;

Copy link
Member

@jdoerfert jdoerfert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test?

@llvmbot llvmbot added the clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' label Jan 24, 2024
Copy link
Member

@jdoerfert jdoerfert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG

@jhuber6 jhuber6 merged commit 0f8b529 into llvm:main Jan 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants